import Storage from '@/lib/storage';
import PREFIX from '@/router/prefix';
import routes from '@/router/routes';
import { deepCopy } from '@/lib/tools';

const ss = new Storage('sessionStorage');
const Cookies = new Storage('cookie');


/**
 * 递归遍历所有菜单转为平级数据
 * @param { Array } list 树状结构
 * @param { Array } res 平级数据结构
 * @returns
 */
function treeForEach(list = [], parentNode = {}, res = {}) {
    list.forEach((node) => {
        node.title = node.name;
        let nodePath = node.path ? PREFIX + node.path : null;
        node.route = nodePath ? { path: nodePath } : null;
        let breadCrumbList = parentNode && parentNode.breadCrumbList || [];
        node.breadCrumbList = [...breadCrumbList, ...[{name: node.title, path: nodePath}]];
        res[nodePath] = node;
        if(node.children && node.children.length) {
            treeForEach(node.children, node, res);
        }
    })
    return res;
}

function getLocalMenuObj () {
    let obj = {};
    routes.length && routes.forEach(item => {
        obj[item.path] = item;
    })
    return obj;
}

const state = {
    initialized: false, // true 初始化完成
    userPermission: {
        sysMenuVOList: [], // 用户菜单
        sysRoleVOList: [], // 用户角色
        flatMenu: {}, // 扁平化的菜单数据
        homeRoute: {} // 首页路由
    }, // 登录用户权限 （接口返回的原始数据）
    currentMenu: {}, // 当前路径对应菜单
    activeMenu: {}, // 高亮菜单
    crumbData: [] // 面包屑
  
};


const getters = {
    // 用户菜单（即该用户角色权限的菜单）
    userMenus: state => {
        return state.userPermission.sysMenuVOList || [];
    },
    userBtnPermission: () => {
        return ss.getItem('BTN_PERMISSION');
    }
};

const actions = {
    // 初始化数据
    init({commit, dispatch, rootState}, dataInfo) {
        return new Promise((resolve, reject) => {
            dispatch('getCurrentUser').then(() => {
                dispatch('getBtnPermissions');
				dispatch('getUserPermissions', {userId: rootState.currentUser.id, ...dataInfo }).then(() => {
					resolve();
                    commit('setState', {
                        key: 'initialized',
                        value: true
                    });
				}).catch((err) => {
					reject(new Error(err))
				})
            }).catch((err) => {
                console.log(err);
                reject(new Error('err'))
            })
        })
    },
    // 获取当前登录用户信息
    getCurrentUser({commit, dispatch, rootState}) {

        return new Promise((resolve, reject) => {
            if (rootState.currentUser.userId) {
                return resolve(rootState.currentUser)
            }

            dispatch('proxyAction', {
                name: 'getCurrentUser'
            }, {
                root: true
            })
                .then((res) => {
                    Cookies.setItem('user-name', res.data.name);
                    commit('meta', {
                        currentUser: {
                            ...res.data
                        }
                    }, {
                        root: true
                    })

                    resolve(res)
                })
                .catch((err) => {
                    reject(err)
                })
        })
    },
    // 获取用户权限菜单
    getUserPermissions({state, commit, dispatch}, dataInfo) {

        return new Promise((resolve, reject) => {
            dispatch('proxyAction', {
                name: 'listUserMenus',
                data: {
                    sys: 'midrange' // 查询中台菜单
                }
            }, {
                root: true
            }).then((res) => {
                let permission = res.data || [];

                if(permission.length === 0) {
                    commit('meta', {
                        pageMessage: {
                            code: 401,
                            message: '您没有权限'
                        }
                    }, {
                        root: true
                    })
                    resolve(res);
                    return;
                }

                const flatMenuObj = treeForEach(permission);

                let localMenus = getLocalMenuObj();
                let homeRoute = state.userPermission?.homeRoute || {}
                let realList = permission.filter(routeItem => {
                    // 如果在路由表或者 不在路由表但是有子菜单
                    let path = `${PREFIX}${routeItem.path}`;
                    if(localMenus[path]) {
                        homeRoute = Object.keys(homeRoute).length ? homeRoute : routeItem;
                        return routeItem;
                    }
                    if(!localMenus[path] && routeItem?.children.length) {
                        homeRoute = Object.keys(homeRoute).length ? homeRoute : routeItem.children[0];
                        return routeItem;
                    }
                })

                commit('setState', {
                    key: 'userPermission',
                    value: {
                        sysMenuVOList: realList,
                        flatMenu: flatMenuObj,
                        homeRoute: homeRoute
                    }
                });
              
                if(dataInfo?.currentPath) {
                    commit('setCurrentMenu', dataInfo);
                    // 查当前路由是否在菜单内
                    let isHavePermission = flatMenuObj[dataInfo.currentPath] ? 1 : 0;
                    // 查当前路由父级是否在菜单内 (路由表中具有parentPath属性的)
                    if(!isHavePermission) {
                        isHavePermission = dataInfo.currentMeta.parentPath && flatMenuObj[`${PREFIX}${dataInfo.currentMeta.parentPath}`] ? 1 : 0;
                    }

                    if(!isHavePermission) {
                        commit('meta', {
                            pageMessage: {
                                code: 405, // 403 没有欢迎页权限退出 // 405 没有当前页面权限
                                message: '您没有当前页面权限'
                            }
                        }, {
                            root: true
                        })
                    }
                }
                resolve({permission: permission, homeRoute: homeRoute});
            }).catch((err) => {
                reject(err)
            })
        })
    },
     // 获取所有按钮权限
    getBtnPermissions({state, commit, dispatch}) {

        return new Promise((resolve, reject) => {
            ss.removeItem('BTN_PERMISSION')

            dispatch('proxyAction', {
                name: 'getWandBtnPermission'
            }, {
                root: true
            }).then((res) => {
                let list = res.data || [];
                let btnMap = {};
                list.length && list.forEach(item => {
                    if(item.tag){
                         btnMap[item.key] = item;
                    }
                })
                ss.setItem('BTN_PERMISSION', btnMap);
                resolve(res)
            }).catch((err) => {
                reject(err)
            })
        })
    },
    // 刷新菜单 & 权限
    reload() {
        window.location.reload();
    },
    reloadMenu({dispatch, rootState}) {
        dispatch('getUserPermissions', {userId: rootState.currentUser.id});
    }
};

const mutations = {
    setState: (state, data) => {
        state[data.key] = data.value;
    },
    setCurrentMenu: (state, data) => {
        let menus = state.userPermission.sysMenuVOList || [];
        let currentMenu = state.userPermission.flatMenu[data.currentPath] || {};
        let breadCrumbList = [];

        if (Object.keys(currentMenu).length <= 0){
            let parentPath = `${PREFIX}${data.currentMeta.parentPath}`;
            currentMenu = state.userPermission.flatMenu[parentPath] || {};
            breadCrumbList = currentMenu && currentMenu?.breadCrumbList?.length && deepCopy(currentMenu.breadCrumbList) || [];
            breadCrumbList = [...breadCrumbList, ...[{name: data.currentMeta.name, path: data.currentPath}]];
        }else {
            breadCrumbList = deepCopy(currentMenu.breadCrumbList) || [];
        }
        if(data.siteRoute?.id) { // 如果是站点列表，则更改为当前选择的站点名称
            breadCrumbList.length && breadCrumbList.forEach((item, index) => {
                 if(item.path.indexOf('/site/list') > -1 && index !== breadCrumbList.length - 1){
                     item.name = data.siteRoute?.name || '';
                     item.path = item.path + '?institutionId=' + data.siteRoute?.id;
                 }
            })
        }
        if (Object.keys(currentMenu).length <= 0){
            return;
        }

        state.currentMenu = currentMenu;
        state.currentTabs = menus.filter(item => item.parentId === currentMenu.parentId);
        state.activeMenu = currentMenu;
        state.crumbData = breadCrumbList || [];
    }
};

export default {
    namespaced: true,
    state,
    getters,
    actions,
    mutations
}
